/* typehints:start */
import { Npc } from "../npcs/npc";
import { GameRoot } from "../root";
/* typehints:end */

import { BattleUnit } from "./battle_unit";
import { createLogger } from "../../core/utils/logging";
import { BasicAi } from "./ai/basic_ai";
import { formatTimeMS, waitNextFrame } from "../../core/utils/utils";

const logger = createLogger('battle/manager');

/**
 * 管理战斗相关内容，如进入战斗（敌我双方）、战斗界面载入、战斗结束结算、战斗进度管理
 */
export class BattleManager{
  constructor(root){
    /** @type {GameRoot} */
    this.root = root;

    this.aiDefine = {
      basicAi: new BasicAi(this.root)
    }
  }

  initialize(){
    this.initData();
  }

  initData(){
    // 战斗回合数
    this.round = 0;
    // 战斗执行时间
    this.time = 0;
    // 我方战斗人物
    this.meBattles = [];
    // 敌方战斗人物
    this.enemyBattles = [];
    // 最大行动数
    this.actionMaxNum = 1000;
    // 当前执行单位
    /** @type {BattleUnit} */
    this.actionUnit = null;
    // 现在是否为玩家选择目标
    this.isPlayerSelectTarget = false;
  }

  /**
   * 创建一个新的战斗
   * @param {Npc} npc
   */
  newBattle(npc){
    this.initData();

    let me = this.root.mainPlayer;

    // 置入基本双方单位
    this.meBattles.push(me);
    this.enemyBattles.push(npc);

    // 获取当前地区是否有一起进入战斗的单位
    let npcs = this.root.worldMap.getCurrentNpcs().filter(item => {
      if(item != npc) return true;
    });

    let isSomeRace = me.data.race == npc.people.data.race;

    npcs.map(item => {
      // 拒绝拉入战斗
      if(item.getIsRefuseBattle()) return;

      // 默认为我方单位
      if(item.getIsMeBattle()){
        this.meBattles.push(item);
        return;
      }

      // 战斗模式下的敌人默认进入敌人单位
      if(item.attr.mode === 1){
        this.enemyBattles.push(item);
        return;
      }

      // 内战
      if(isSomeRace){
        // 只有一样的生物才会进入战斗
        if(item.getName() == npc.getName()) {
          this.enemyBattles.push(item);
        }
      } else {
        if(item.people.data.race == npc.people.data.race){
          this.enemyBattles.push(item);
        }
      }
    });
    
    if(this.root.playerData.troops.length > 1){
      let { confirm } = this.root.gameState.dialogs.showOptionMultiple('选择你的队友', {
        options: this.root.playerData.troops.filter(item => {
          if(item.data._id !== me.data._id) return true;
        }).map(item => ({
          value: item.data._id,
          text: item.getName()
        }))
      })

      confirm.add(data => {
        this.meBattles = [...this.meBattles, ...this.root.playerData.troops.filter(item => {
          if(data.indexOf(item.data._id) >= 0) return true;
        })]

        this.playBattle();
      })
    } else {
      this.playBattle();
    }
  }

  // 开始战斗
  playBattle(){
    this.meBattles = this.meBattles.map(item => {
      return new BattleUnit(this.root, item, 'me');
    })
    this.enemyBattles = this.enemyBattles.map(item => {
      return new BattleUnit(this.root, item, 'enemy');
    });

    let maxAction = 0;

    this.getAllUnit().map(item => {
      item.initialize();

      let action = item.people.getActionNum();
      if(action > maxAction) maxAction = action;
    })

    this.actionMaxNum = maxAction * 100;

    // 进入战斗模式
    this.root.playBattle();
    this.root.message('log', '系统', 
      `----- 玩家与<${this.enemyBattles[0].people.getName()}>战斗 -----`, 'log');
    this.root.hud.parts.battlePage.handleShow();
  }

  // 获取我方所有单位
  getCorrectUnits(type){
    return type == 'me' ? this.meBattles : this.enemyBattles;
  }

  // 获取敌方所有单位
  getOtherUnits(type){
    return type == 'me' ? this.enemyBattles : this.meBattles;
  }

  getUnitIndex(unit){
    let arr = this.getCorrectUnits(unit.type);
    let index = -1;

    for(let i = 0; i < arr.length; i++){
      if(arr[i] == unit) index = i;
    }

    return index;
  }

  getAllUnit(){
    return [...this.meBattles, ...this.enemyBattles];
  }

  // 设置活动单元
  setActionUnit(unit){
    this.actionUnit = unit;
    // logger.log(`现在由<${unit.people.getName()}>执行动作`);
    this.root.message('alert', `${unit.type == 'me' ? '我方' : '敌方'}<${unit.people.getName()}>的回合`, 1000);

    // TODO 后续修改为玩家给单位设置了Ai控制
    // 判断单元是否为玩家操作
    if(unit.npc){
      // npc操作
      let ai = this.aiDefine[this.actionUnit.npc.getBattleAi()] || this.aiDefine.basicAi;
      ai.runAction();
    } else {
      // 显示玩家操作
      this.root.hud.parts.battlePage.showPlayerControl();
    }
    
    if(this.root.app.setting.getSetting('posUnitScrollTop')){
      this.root.hud.parts.battlePage.scrollToIndex(this.actionUnit);
    }
  }

  // 执行当前动作
  runAction(){
    let action = this.actionUnit.action;
    // 不管如何，玩家的控制权都会关闭
    this.isPlayerSelectTarget = false;
    this.root.hud.parts.battlePage.hidePlayerControl();

    if(!action.skill || action.targets.length <= 0){
      this.endAction();
      return;
    }

    this.root.message('log', '系统', `${this.actionUnit.people.getName()}使用<${action.skill.getName()}>向${action.targets.map(item => `<${item.people.getName()}>`).join('')}释放`, 'log');

    this.actionUnit.showText(action.skill.getName())

    // 显示与目标的连接线
    this.root.hud.parts.battlePage.drawSvgLine(this.actionUnit, action.targets);

    this.actionUnit.element.classList.add('move');

    // 延迟是为了增加操作感
    setTimeout(() => {
      action.skill.implement().then(() => {
        setTimeout(() => {
          this.actionUnit.element.classList.remove('move');
          this.endAction();
        }, 500);
      })
    }, 500);
  }

  // 结束当前动作
  endAction(){
    this.actionUnit.endAction();
    this.actionUnit = null;
  }

  // 更新时间
  updateTime(){
    this.time++;
    this.root.hud.parts.battlePage.element.querySelector('.time span').innerHTML = formatTimeMS(this.time);
  }

  update(){
    let units = this.getAllUnit();

    this.root.time.run('battleUpdate', () => {
      this.updateTime();
    }, 1000)

    units.map(item => {
      if(!this.actionUnit){
        item.addActionNum();
      }

      item.update();
    })
  }
}